package com.itany.corejava.code08_常用类.string;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * @author 石小俊
 * @date 2023年04月26日 10:28
 */
public class Test07_字符集 {

    public static void main(String[] args) throws UnsupportedEncodingException {
//        showEncoding();
//        encoded();
//        decoded();
//        garbled();
        garbled2();
    }

    public static void showEncoding() {
        // 当前系统所使用的字符集
        System.out.println("当前系统所使用的字符集为:" + System.getProperty("file.encoding"));
        // JVM默认使用的字符集即为当前系统的字符集
        System.out.println("JVMJVM默认使用的字符集:" + Charset.defaultCharset());
    }

    public static void encoded() throws UnsupportedEncodingException {
        String s = "你好";
        // 对于GBK编码,占2个字节
        byte[] bytes = s.getBytes("GBK");
        // [-60, -29, -70, -61]
        System.out.println(Arrays.toString(bytes));
        // 对于UTF-8,占3个字节
        byte[] bytes2 = s.getBytes("UTF-8");
        // [-28, -67, -96, -27, -91, -67]
        System.out.println(Arrays.toString(bytes2));
    }

    public static void decoded() throws UnsupportedEncodingException {
        // 使用GBK字符集进行解码
        byte[] bytes = {-60, -29, -70, -61};
        String s = new String(bytes, "GBK");
        System.out.println(s);

        // 使用UTF-8的字符集进行解码
        byte[] bytes2 = {-28, -67, -96, -27, -91, -67};
        String s2 = new String(bytes2, "UTF-8");
        System.out.println(s2);

        // 使用系统默认的字符集进行解码
        String s3 = new String(bytes2);
        System.out.println(s3);
    }

    /**
     * 乱码
     */
    public static void garbled() throws UnsupportedEncodingException {
        String s = "你好";
        // 编码 --> 使用GBK进行编码
        byte[] bytes = s.getBytes("GBK");
        System.out.println(Arrays.toString(bytes));
        // 解码 --> ISO-8859-1进行解码
        String s2 = new String(bytes, "ISO-8859-1");
        // 此时由于编码与解码所采用的规则不一致,产生了乱码
        System.out.println(s2);

        // 乱码的解决方式
        // 由于解码时使用的是ISO-8859-1,与编码字符集不一致
        // 则再次重新编码,编码时使用之前解码时所采用的编码
        byte[] bytes2 = s2.getBytes("ISO-8859-1");
        // 此时获取的字节数组即为第一次编码后的数组
        System.out.println(Arrays.toString(bytes2));
        // 再以第一次编码所采用的字符集进行解码即可
        String s3 = new String(bytes2, "GBK");
        System.out.println(s3);

        // 简写方式
        s3 = new String(s2.getBytes("ISO-8859-1"), "GBK");
        System.out.println(s3);
    }

    /**
     * GBK不符合UTF-8的规则,无法解决乱码问题
     */
    public static void garbled2() throws UnsupportedEncodingException {
        String s = "你好";
        byte[] bytes = s.getBytes("GBK");
        System.out.println(Arrays.toString(bytes));
        String s2 = new String(bytes, "UTF-8");
        System.out.println(s2);

        // 此时的GBK不符合UTF-8的规则
        // 在解码时,会导致原字符串的长度发生变化
        // 2个字符 --> 4个字节 --> 3个字符  --> 9个字节
        // 这种情况无法恢复
        byte[] bytes2 = s2.getBytes("UTF-8");
        System.out.println(Arrays.toString(bytes2));
    }

    /**
     * UTF-8符合GBK的规则,则可以解决乱码问题
     */
    public static void garbled3() throws UnsupportedEncodingException {
        String s = "你好";
        byte[] bytes = s.getBytes("UTF-8");
        System.out.println(Arrays.toString(bytes));

        String s2 = new String(bytes, "GBK");
        System.out.println(s2);

        // 由于UTF-8是属于国际标准字符集,其他字符集的规则UTF-8基本都满足
        // 因此,此时可以解码
        byte[] bytes2 = s2.getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));
        String s3 = new String(bytes2, "UTF-8");
        System.out.println(s3);
    }

}
